package com.meida.module.pay.provider.handler;

import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayMessageInterceptor;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.google.common.collect.ImmutableSet;
import com.meida.common.constants.CommonConstants;
import com.meida.module.pay.client.enums.PayType;

import java.util.Map;
import java.util.Set;

/**
 * 支付处理器接口
 *
 * @author zyf
 */
public interface PaySuccessHandler extends PayMessageInterceptor<PayMessage, PayService>, PayMessageHandler<PayMessage, PayService> {
    Set<String> TRADE_STATUSES = ImmutableSet.of("TRADE_SUCCESS", "TRADE_FINISHED");

    /**
     * 自定义业务校验,比如验证是否已支付
     *
     * @param payMessage 支付回调消息
     * @param context    上下文参数,可传递到success方法内
     * @param payService 支付服务
     */
    boolean validate(PayMessage payMessage, Map<String, Object> context, PayService payService, String outTradeNo);

    /**
     * 自定义支付成功回调
     *
     * @param payMessage 支付回调消息
     * @param outTradeNo 订单号
     * @param context    上下文参数
     * @param payService 支付服务
     * @return
     */
    boolean success(PayMessage payMessage, String outTradeNo, Map<String, Object> context, PayService payService);

    /**
     * 支付回调成功前处理
     * @param payMessage
     * @param context
     * @param payService
     * @return
     * @throws PayErrorException
     */
    @Override
    default PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
        String payCode = String.valueOf(payService.getPayConfigStorage().getPayType());
        Map<String, Object> message = payMessage.getPayMessage();

        //支付宝
        if (PayType.aliPay.name().equals(payCode)) {
            //交易状态
            String trade_status = (String) message.get("trade_status");
            //支付成功或支付完成
            if (TRADE_STATUSES.contains(trade_status)) {
                String outTradeNo = payMessage.getOutTradeNo();
                Boolean tag = success(payMessage, outTradeNo, context, payService);
                if (tag) {
                    return payService.getPayOutMessage(CommonConstants.SUCCESS.toLowerCase(), "成功");
                }
            }
        }
        //微信支付
        if (PayType.wxPay.name().equals(payCode)) {
            //交易状态
            String result_code = (String) message.get("result_code");
            if (CommonConstants.SUCCESS.equals(result_code)) {
                String outTradeNo = payMessage.getOutTradeNo();
                success(payMessage, outTradeNo, context, payService);
                return payService.getPayOutMessage(CommonConstants.SUCCESS, "成功");
            } else {
                return payService.getPayOutMessage(CommonConstants.FAIL, "失败");
            }
        }
        return payService.getPayOutMessage("fail", "失败");
    }

    /**
     * 支付回调前校验
     *
     * @param payMessage
     * @param context
     * @param payService
     * @return
     * @throws PayErrorException
     */
    @Override
    default boolean intercept(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
        String outTradeNo = payMessage.getOutTradeNo();
        return validate(payMessage, context, payService, outTradeNo);
    }
}
